home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / COMMON.ZIP / PCX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  3.6 KB  |  134 lines

  1. /*
  2.  
  3.     pcx.c
  4.  
  5.     Internet: alexad3@icebox.iceonline.com
  6.     Copyright 1995, April 6 by Alec Russell, ALL rights reserved
  7.     Permission granted to use this code as anyone wishes.
  8.  
  9.     Created - 1995/4/6
  10.  
  11.     History:
  12.         New file
  13.  
  14.     Originally programmed for medium mem model, thus the liberal
  15.     lacing of FAR * throughout the code.
  16.  
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. #include <xfileio.h>
  23. #include <gmalloc.h>
  24.  
  25.  
  26. // for all pcx files (far as I know)
  27. typedef struct
  28.    {
  29.    char manu; /// usually 10
  30.    char version;
  31.    char encoding;
  32.    char bits_per_pixel;
  33.    int xmin, ymin, xmax, ymax;
  34.    int hres, yres;
  35.    char palette[48];  // not used by 256 color pcx
  36.    char reserved;
  37.    char color_planes;
  38.    int bytes_per_line;
  39.    int palette_type;
  40.    char spare[58];
  41.    }
  42. pcx_head_t;
  43.  
  44.  
  45. #define PAL_SIZE 768
  46. #define PCX_HD_SIZE 128
  47.  
  48. /* for 256 color PC images ONLY, works with dpaint images
  49.    Make sure b is big enough for unpacked image.
  50.    Don't use this to get ideas for compression as
  51.    there are much better ways to do even simple RLE encoding.
  52. */
  53. /* ---------------------- unpack_pcx() ------------------ January 4,1995 */
  54. int unpack_pcx(char *fname, unsigned char far *b, unsigned char *pal,
  55.                int *p_width, int *p_height)
  56. {
  57.    int err=0, i;
  58.    unsigned int size;
  59.    pcx_head_t pcx;
  60.    unsigned char far *t1, far *raw;
  61.  
  62.    raw=far_load(fname);  // load the whole file into mem,
  63.                          // an easy function to write
  64.  
  65.    size=load_size;       // load_size is a global set by far_load()
  66.                          // if not obvious load_size is file size
  67.    if ( raw )
  68.       {
  69.       if ( size > PCX_HD_SIZE )
  70.          {
  71.          _fmemcpy(&pcx, raw, PCX_HD_SIZE);  // far memcpy
  72. #if 0
  73. // debug stuff
  74. pr2("manu %d", pcx.manu);
  75. pr2("ver  %d", pcx.version);
  76. pr2("enc  %d", pcx.encoding);
  77. pr2("bits %d", pcx.bits_per_pixel);
  78. pr2("xmin %d ymin %d xmax %d ymax %d",
  79.     pcx.xmin, pcx.ymin, pcx.xmax, pcx.ymax);
  80. pr2("hres %d yres %d", pcx.hres, pcx.yres);
  81. pr2("rsv %d", pcx.reserved);
  82. pr2("planes %d", pcx.color_planes);
  83. pr2("bytes/line %d", pcx.bytes_per_line);
  84. pr2("pal type %d", pcx.palette_type);
  85. #endif
  86.          // get width and height
  87.          *p_width =pcx.xmax - pcx.xmin + 1;
  88.          *p_height=pcx.ymax - pcx.ymin + 1;
  89.          // get palette
  90.          // the palette is just tacked onto the end of the file
  91.          _fmemcpy(pal, raw+size-PAL_SIZE, PAL_SIZE);
  92.          for ( i=0, t1=pal; i < PAL_SIZE; i++, t1++ )
  93.             *t1>>=2;
  94.  
  95.          // this type of de-compression is common to most pcx files
  96.  
  97.          t1=raw+PCX_HD_SIZE; // skip header
  98.          // decompress raw into b
  99.          size-=PCX_HD_SIZE; // skip header
  100.          size-=PAL_SIZE; // don't include palette at end
  101.          while ( size )
  102.             {
  103.             if ( (*t1 & 0xc0) == 0xc0 ) // are the two high bits set?
  104.                {
  105.                // hi bits set, its a run
  106.                i=*t1 & 0x3f;    // mask with 00111111 to get size of run
  107.                t1++;            // next byte is color to repeat
  108.                size--;
  109.                while ( i-- )
  110.                   *b++=*t1;
  111.                t1++;
  112.                size--;
  113.                }
  114.             else
  115.                {
  116.                *b++=*t1++;  // not a run, copy one byte
  117.                size--;
  118.                }
  119.             }
  120.  
  121.          gfree(raw, "raw");  // like a free()
  122.          }
  123.       else
  124.          err=2;
  125.       }
  126.    else
  127.       err=1;
  128.  
  129.    return(err);
  130. }
  131.  
  132. /* ------------------------------ EOF -------------------------------- */
  133.  
  134.